﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;

using System.Configuration;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint.Utilities;
using de.rwth.rz.campus.sputils.Security;


namespace de.rwth.rz.campus.Mailer
{

    /// <remarks>
    /// 
    /// Copyright 2010 RWTH Aachen, CAMPUS Labs
    /// 
    /// Licensed under the Apache License, Version 2.0 (the "License");
    /// you may not use this file except in compliance with the License.
    /// You may obtain a copy of the License at
    ///
    /// http://www.apache.org/licenses/LICENSE-2.0
    ///
    /// Unless required by applicable law or agreed to in writing, software
    /// distributed under the License is distributed on an "AS IS" BASIS,
    /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    /// See the License for the specific language governing permissions and
    /// limitations under the License.
    /// 
    /// </remarks>

    [CLSCompliant(false)]
    public class GroupField : SPFieldMultiColumn
    {
        public GroupField(SPFieldCollection fields, string fieldName) : base(fields, fieldName) { }
        public GroupField(SPFieldCollection fields, string fieldName, string displayName) : base(fields, fieldName, displayName) { }

        // Override, to tell Sharepoint which control to use to render the field
        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                BaseFieldControl control = new GroupFieldControl();
                control.FieldName = this.InternalName;
                return control;
            }
        }

        public override string GetValidatedString(object value)
        {
            return base.GetValidatedString(value);
        }
    }

    [CLSCompliant(false)]
    public class GroupFieldControl : BaseFieldControl
    {
        protected InputFormCheckBoxList GroupSelector;
        protected InputFormCheckBoxList SiteGroupSelector;

        private const string IncludeScriptKey = "includeScript";
        private const string EmbeddedScript = "<script language=\"javascript\" type=\"text/javascript\">function DoCheck(chkListId){ "
                                            + " var chk = document.getElementById(chkListId); "
                                            + " var box = chk.getElementsByTagName('input'); "
                                            + " var ischecked =  box[0].checked; "
                                            + " for(i = 1; i < box.length; i++){ "
                                            + " box[i].checked = ischecked; }}"
                                            + "</script>";

        public GroupFieldControl()
        {
            this.PreRender += new EventHandler(ClientScript_PreRender);
        }

        private void ClientScript_PreRender(object sender, System.EventArgs e)
        {
            if (!this.Page.ClientScript.IsClientScriptBlockRegistered(IncludeScriptKey))
                this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), IncludeScriptKey, EmbeddedScript);
        }

        protected override string DefaultTemplateName
        {
            get
            {
                return @"GroupFieldControl";
            }
        }

        public override void Validate()
        {
            if ((base.ControlMode != SPControlMode.Display) && base.IsValid)
            {
                base.Validate();
                if (base.Field.Required && (this.GroupSelector.SelectedIndex == -1))
                {
                    base.IsValid = false;
                    base.ErrorMessage = SPResource.GetString("MissingRequiredField", new object[0]);
                }
            }
        }

        public override object Value
        {
            get
            {
                EnsureChildControls();
                SPFieldMultiColumnValue fieldValue = new SPFieldMultiColumnValue();
                for (int i = 0; i < GroupSelector.Items.Count; i++)
                {
                    if (GroupSelector.Items[i].Selected) { fieldValue.Add(GroupSelector.Items[i].Value); }
                }
                if (ShowSiteGroupSelector)
                {
                    for (int i = 0; i < SiteGroupSelector.Items.Count; i++)
                    {
                        if (SiteGroupSelector.Items[i].Selected) { fieldValue.Add(SiteGroupSelector.Items[i].Value); }
                    }
                }
                return fieldValue;
            }
            set
            {
                EnsureChildControls();
                GroupSelector.ClearSelection();
                SiteGroupSelector.ClearSelection();
                SPFieldMultiColumnValue fieldValue = (SPFieldMultiColumnValue)value;
                for (int i = 0; i < fieldValue.Count; i++)
                {
                    if (GroupSelector.Items.FindByValue(fieldValue[i]) != null)
                        GroupSelector.Items.FindByValue(fieldValue[i]).Selected = true;
                    else if (ShowSiteGroupSelector && SiteGroupSelector.Items.FindByValue(fieldValue[i]) != null)
                        SiteGroupSelector.Items.FindByValue(fieldValue[i]).Selected = true;
                }
            }
        }

        bool ShowSiteGroupSelector
        {
            get
            {
                SPProperties settings = new SPProperties(SPContext.Current.Web);
                if (settings["_" + this.ListId + "sHOW"] == bool.TrueString)
                    return true;
                return false;
            }
        }


        protected override void CreateChildControls()
        {
            if (this.Field == null || this.ControlMode == SPControlMode.Display)
                return;

            base.CreateChildControls();
            this.GroupSelector = (InputFormCheckBoxList)TemplateContainer.FindControl("GroupSelector");
            if (this.GroupSelector == null)
                throw new ConfigurationErrorsException("Corrupted Controltemplate file.");
            //GroupSelector.Items.FindByValue("0").Attributes["onclick"] = "DoCheck('" + GroupSelector.ClientID + "');";
            //GroupSelector.Items.FindByValue("0").Attributes["class"] = "ms-vh2";
            //GroupSelector.Items.FindByValue("0").Text = SPUtility.GetLocalizedString("$Resources:Mailer,AllGroups", "Mailer", SPContext.Current.Web.Language) + "</td><td>";
            //((InputFormCheckBox)TemplateContainer.FindControl("SelectAll")).Text = SPUtility.GetLocalizedString("$Resources:Mailer,AllGroups", "Mailer", SPContext.Current.Web.Language) + "</td><td>"; 

            this.SiteGroupSelector = (InputFormCheckBoxList)TemplateContainer.FindControl("SiteGroupSelector");
            if (ShowSiteGroupSelector)
            {
                this.SiteGroupSelector.Visible = true;
                ((HtmlControl)TemplateContainer.FindControl("trheader")).Style["display"] = "";
            }
            else
            {
                this.SiteGroupSelector.Visible = false;
                ((HtmlControl)TemplateContainer.FindControl("trheader")).Style["display"] = "none";
            }

            if (!Page.IsPostBack)
            {
                List<int> ids = new List<int>();

                //Elevated Rights, necessary because of using SPGroup.Users Property
                using (SPSite site = SPSiteSecurity.GetElevatedSite(SPContext.Current.Site))
                {
                    foreach (SPGroup group in site.OpenWeb(SPContext.Current.Web.ID).Groups)
                    {
                        int iUser = group.Users.Count;
                        if(group.ContainsCurrentUser)
                            iUser--;
                        ListItem item = new ListItem(group.Name + "</td><td>(" + iUser + ")", group.Name);
                        item.Attributes["class"] = "ms-RadioText";
                        //item.Attributes["style"] = "padding-left: 15px";
                        GroupSelector.Items.Add(item);
                        ids.Add(group.ID);
                    }

                    if (ShowSiteGroupSelector)
                    {
                        foreach (SPGroup group in site.OpenWeb().SiteGroups)
                        {
                            if (!ids.Contains(group.ID))
                            {
                                int iUser = group.Users.Count;
                                if (group.ContainsCurrentUser)
                                    iUser--;
                                ListItem item = new ListItem(group.Name + "</td><td>(" + iUser + ")", group.Name);
                                item.Attributes["class"] = "ms-RadioText";
                                SiteGroupSelector.Items.Add(item);
                            }
                        }
                    }
                }
            }
        }
    }
}
